package xyz.xiezc.mzix.download.service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import xyz.xiezc.mzix.common.api.Download;
import xyz.xiezc.mzix.common.dto.PageDTO;
import xyz.xiezc.mzix.common.dto.Request;
import xyz.xiezc.mzix.common.dto.Response;
import xyz.xiezc.mzix.download.feign.ScheduleService;

import javax.annotation.PostConstruct;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 下载网页
 */
@Component
public class DownloadService implements Download {

  @Autowired
  private ScheduleService scheduleService;

  private HttpClient httpClient;

  @PostConstruct
  public void init() {
    httpClient = HttpClient.newBuilder()
        .version(HttpClient.Version.HTTP_1_1)
        .followRedirects(HttpClient.Redirect.NORMAL)
        .connectTimeout(Duration.ofSeconds(20))
        //.proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
        // .authenticator(Authenticator.getDefault())
        .build();
  }


  @Override
  @SneakyThrows
  public void download(PageDTO pageDTO) {
    Request request = pageDTO.getRequest();
    HttpRequest httpRequest = request.buildHttpRequest();

    //根据请求
    HttpResponse<InputStream> httpResponse = httpClient
        .send(httpRequest, HttpResponse.BodyHandlers.ofInputStream());

    Map<String, List<String>> headers = httpResponse.headers().map();
    List<String> contentTypes = headers.getOrDefault("Content-Type", new ArrayList<>());
    contentTypes.addAll(headers.getOrDefault("content-type", new ArrayList<>()));
    Response response = new Response();
    pageDTO.setResponse(response);
    String contentType = this.contain(contentTypes, Arrays.asList("text/html", "text/json"));
    if (StringUtils.isEmpty(contentType)) {
      BufferedInputStream bufferedInputStream = new BufferedInputStream(httpResponse.body());
      byte[] bytes = bufferedInputStream.readAllBytes();
      response.setBody(bytes);
    }
    contentType = this.contain(contentTypes, Arrays.asList("image/jpeg", "image/png"));
    if (StringUtils.isEmpty(contentType)) {
      String dir = scheduleService.getSession(pageDTO.getCode(), "img.dir");
      if (StrUtil.isEmpty(dir)) {
        dir = System.getProperty("user.dir");
      }
      File file = FileUtil.writeFromStream(httpResponse.body(), dir);
      pageDTO.getAttribute().put("dir", FileUtil.getAbsolutePath(file));
    }

    pageDTO.setContentType(contentType);
    response.setUrl(httpResponse.uri().toString());
    response.setHeaders(headers);
    response.setStatusCode(httpResponse.statusCode());
  }


  public String contain(List<String> contentTypes, List<String> types) {
    for (String type : contentTypes) {
      for (String s : types) {
        if (type.contains(s)) {
          return s;
        }
      }
    }
    return null;
  }

}
